/*
 * @Description:表格文件上传组件
 * @Author: hyx
 * @Date: 2021-03-24 9:40
 */
import { PropType, defineComponent, watch, onMounted, App, Plugin, ref } from 'vue'
import { isString, fileNameReplace } from '@/utils/tools'
import { isEmpty, isNil, map, not, equals, concat, includes } from 'ramda'
import { message, notification } from 'ant-design-vue'
import { AilOSS, OssData, XYFile } from '@/utils/upload'
import { FileInfo } from '.'
import { errorTips } from '@/utils'
type UploadFileStatus = 'error' | 'success' | 'done' | 'uploading' | 'removed'
const fileStatus = ['removed', 'done']
interface UploadChangeParam {
    file: UploadFile
    fileList: Array<UploadFile>
}
interface UploadFile<T = any> {
    byte: string
    uid: string
    size: number
    name: string
    fileName?: string
    lastModified?: number
    lastModifiedDate?: Date
    url?: string
    status?: UploadFileStatus
    percent?: number
    thumbUrl?: string
    originFileObj?: XYFile
    response?: T
    error?: any
    linkProps?: any
    type: string
    xhr?: T
    preview?: string
}
const Props = {
    value: [String, Array] as PropType<string | Array<string>>,
    multiple: {
        type: Boolean as PropType<boolean>,
        default: false,
    },
    disabled: {
        type: Boolean as PropType<boolean>,
        default: false,
    },
    maxLength: Number as PropType<number>,
    buttonText: {
        type: String as PropType<string>,
        default: '点击上传',
    },
    /** 文件格式 */
    accept: {
        type: String as PropType<string>,
        default: '*',
    },
}
export default defineComponent({
    name: 'uploadFiles',
    props: Props,
    emits: ['change', 'update:value'],
    setup(props, { emit }) {
        const maxLength = props.multiple ? props.maxLength || 12 : props.maxLength || 1
        const uploadFileList = ref<Array<OssData>>([])
        const loading = ref(false)
        onMounted(() => {
            setfileList()
        })
        watch(
            () => props.value,
            () => {
                setfileList()
            }
        )

        async function handleChange({ file, fileList }: UploadChangeParam) {
            if (!equals(props.accept, '*')) {
                const reg = props.accept.split(',').map(ext => ext.trim().replace(/\.[^.]+$/, match => match.replace('.', ''))).join('|')
                if (!new RegExp(`\\.(${reg})$`, 'i').test((file as any).name.toLowerCase())) {
                    message.error(`上传格式不正确，请上传${props.accept}格式`)
                    loading.value = false
                    return false
                }
            }

            loading.value = true
            try {
                // 删除或者传成功都通知的表单更新
                if (includes(file.status as string, fileStatus)) {
                    loading.value = false
                    const value = map((item) => {
                        return {
                            url: item.url,
                            name: item.name,
                        }
                    }, fileList)
                    emit('update:value', value)
                    emit('change', value)
                    return
                }
                const data = await AilOSS.uploadOSS(file as any)
                fileList = map((item) => {
                    if (`${file.uid}-${fileNameReplace(file.name)}` === data.filename) {
                        item.url = data.url
                        item.byte = (file.size / (1024 * 1024)).toFixed(4)
                        item.size = 0
                    }
                    return item
                }, fileList)
                uploadFileList.value = fileList as any
                emit('change', uploadFileList.value)
            } catch (error) {
                loading.value = false
                // 上传失败需要处理一下 错误信息 免得错误太长 阻挡删除按钮
                if (equals(file.status as string, 'error')) {
                    fileList = map((item) => {
                        if (equals(item.status as string, 'error')) {
                            item.response = '上传失败'
                        }
                        return item
                    }, fileList)
                }
                uploadFileList.value = fileList as any
                errorTips('上传文件失败:' + error)
            }
            // 如果想进行更多操作或者显示到页面上，可以根据需求修改下面的代码

        }
        function setfileList() {
            if (isNil(props.value) || isEmpty(props.value)) {
                uploadFileList.value = []
            } else {
                uploadFileList.value = map(
                    (item: any) => {
                        return {
                            url: item.url,
                            name: item.name,
                            type: 'image/png',
                        }
                    },
                    isString(props.value) ? [props.value] : props.value
                )
            }
        }

        return () => (
            <a-upload
                before-upload={() => false}
                disabled={props.disabled}
                multiple={props.multiple}
                maxLength={props.maxLength}
                onChange={handleChange}
                fileList={uploadFileList.value}
                accept={props.accept}
            >

                {uploadFileList.value.length >= maxLength ? null : <a-button type="link" loading={loading.value}>{props.buttonText}</a-button>}
            </a-upload>
        )
    },
})
